home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
tools
/
czesc_3
/
reminder
/
src
/
calcdate.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-04-19
|
6KB
|
235 lines
/* Date calculation routines for Reminder and ReminderCheck */
/* $Id: CalcDate.c,v 1.1 1993/04/04 13:37:45 Matti_Rintala Exp $ */
#include "Constants.h"
#include "CalcDate.h"
#define min(a,b) (((a)<(b)) ? (a) : (b))
static monthlen[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/* makedate calculates next date that satisfies given conditions */
void makedate(time_t *date, time_t *today,
short dday, short dmonth, short dyear, short dwday) {
struct tm d;
int found;
short year, month, day;
short year_max, month_max, day_max;
short year_now, month_now, day_now;
d = *localtime(today); /* Current date */
day_now = d.tm_mday;
month_now = d.tm_mon + 1;
year_now = d.tm_year + 1900;
found = FALSE;
year = dyear;
if (year != 0)
year_max = year; /* Year is not wildcard */
else {
year = year_now; /* Otherwise start form now */
year_max = MAXYEAR;
}
/* Go through all possible years */
for (; year <= year_max; year++) {
/* If we are in the past, try another */
if (year < year_now)
continue;
month = dmonth;
if (month != 0)
month_max = month; /* Month is not wildcard */
else {
month = (year == year_now) ? month_now : 1; /* Start from now */
month_max = 12;
}
/* If we are in the past, try another year */
if (year == year_now && month_max < month_now)
continue;
/* Go through all possible months */
for (; month <= month_max; month++) {
day = dday;
day_max = monthlen[month-1] + ((year%4 == 0) ?
((year%400 == 0) ? 0 : 1) : 0);
if (day != 0) {
if (dwday == 0)
day_max = day; /* No wildcards in day */
else {
day = min(day, day_max);
day_max = min(day+6, day_max); /* Scope is one week */
}
}
else { /* Day is a wildcard */
day = (year == year_now && month == month_now) ? day_now : 1;
}
/* If we are in the past, try another month */
if (year == year_now && month == month_now && day_max < day_now)
continue;
/* We should not start earlier than present */
if (year == year_now && month == month_now && day < day_now)
day = day_now;
/* We have to find the day */
for (; day <= day_max; day++) {
if (dwday == 0 || dwday == weekday(day, month, year)) {
found =TRUE;
break;
}
}
if (found) break;
}
if (found) break;
}
/* If found, use the date */
if (found) {
/* Now calculate the date */
d.tm_sec = d.tm_min = d.tm_hour = 0;
d.tm_mday = day;
d.tm_mon = month - 1;
d.tm_year = year - 1900;
*date = mktime(&d); /* Make the date */
}
else {
/* Else try previous one */
makeprevdate(date, today, dday, dmonth, dyear, dwday);
}
}
/* makeprevdate calculates previous date that satisfies given conditions */
void makeprevdate(time_t *date, time_t *today,
short dday, short dmonth, short dyear, short dwday) {
struct tm d;
int found;
short year, month, day;
short year_min, month_min, day_min;
short year_now, month_now, day_now;
d = *localtime(today); /* Current date */
day_now = d.tm_mday;
month_now = d.tm_mon + 1;
year_now = d.tm_year + 1900;
found = FALSE;
year = dyear;
if (year != 0)
year_min = year; /* Year is not wildcard */
else {
year = year_now; /* Otherwise start form now */
year_min = MINYEAR;
}
/* Go through all possible years */
for (; year >= year_min; year--) {
/* If we are in the future, try next */
if (year > year_now)
continue;
month = dmonth;
if (month != 0)
month_min = month; /* Month is not wildcard */
else {
month = (year == year_now) ? month_now : 12; /* Start from now */
month_min = 1;
}
/* If we are in the future, try another year */
if (year == year_now && month_min > month_now)
continue;
/* Go through all possible months */
for (; month >= month_min; month--) {
day_min = dday;
day = monthlen[month-1] + ((year%4 == 0) ?
((year%400 == 0) ? 0 : 1) : 0);
if (day_min != 0) {
if (dwday == 0)
day = day_min; /* No wildcards in day */
else {
day = min(day_min+6, day); /* Scope is one week */
}
}
else { /* Day is a wildcard */
day = (year == year_now && month == month_now) ? day_now : day;
day_min = 1;
}
/* If we are in the future, try another month */
if (year == year_now && month == month_now && day_min > day_now)
continue;
/* We should not start later than present */
if (year == year_now && month == month_now && day > day_now)
day = day_now;
/* We have to find the day */
for (; day >= day_min; day--) {
if (dwday == 0 || dwday == weekday(day, month, year)) {
found =TRUE;
break;
}
}
if (found) break;
}
if (found) break;
}
d.tm_sec = d.tm_min = d.tm_hour = 0;
/* If date found */
if (found) {
/* Now calculate the date */
d.tm_mday = day;
d.tm_mon = month - 1;
d.tm_year = year - 1900;
}
else {
/* Else use 1.1.1990 */
d.tm_mday = 1;
d.tm_mon = 0;
d.tm_year = 90;
}
*date = mktime(&d); /* Make the date */
}
/* weekday gives the day of the week */
short weekday(short day, short month, short year) {
struct tm date;
time_t time;
date.tm_sec = date.tm_min = date.tm_hour = 0;
date.tm_mday = day;
date.tm_mon = month - 1;
date.tm_year = year - 1900;
time = mktime(&date); /* Make a time_t */
date = *localtime(&time); /* Calculate back to struct */
/* Day of the week is now in date */
return (short)((date.tm_wday == 0) ? 7 : date.tm_wday);
}
/* gettoday gets today's date (without time of day) */
void gettoday(time_t *today) {
struct tm *tmptr;
time(today); /* Get date */
tmptr = localtime(today); /* Change to struct */
/* Now zero all time of day fields */
tmptr->tm_sec = tmptr->tm_min = tmptr->tm_hour = 0;
*today = mktime(tmptr); /* Convert back to time_t */
}